1 /*
2  * The MIT License (MIT)
3  *
4  * Copyright (c) 2014 Devisualization (Richard Andrew Cattermole)
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 module devisualization.util.opengl.buffers;
25 import devisualization.util.opengl.function_wrappers;
26 import devisualization.image;
27 public import devisualization.util.opengl.function_wrappers : BindBufferTargets, BufferUsages;
28 public import gl3n.linalg : vec4, vec3, vec2, mat2, mat3, mat34, mat4;
29 
30 alias Buffer!(BufferUsages.StaticDraw, BindBufferTargets.ArrayBuffer) StandardBuffer;
31 alias Buffer!(BufferUsages.StaticDraw, BindBufferTargets.ElementArrayBuffer) IndexBuffer;
32 
33 deprecated("de_util:opengl is going to die"):
34 
35 struct IBuffer {
36     private {
37         void delegate() bind1;
38         void delegate(BindBufferTargets type) bind2;
39     }
40 
41     void bind() {
42         bind1();
43     }
44 
45     void bind(BindBufferTargets type) {
46         bind2(type);
47     }
48 }
49 
50 class Buffer(BufferUsages _usage, BindBufferTargets _type) {
51     private {
52         uint id_;
53     }
54 
55 	IBuffer this_;
56 	alias this_ this;
57 
58     this(vec2[] data...) {
59         float[] vals;
60         foreach(v; data) vals ~= v.vector;
61         this(cast(void[])vals);
62     }
63     
64     this(vec3[] data...) {
65         float[] vals;
66         foreach(v; data) vals ~= v.vector;
67         this(cast(void[])vals);
68     }
69     
70     this(vec4[] data...) {
71         float[] vals;
72         foreach(v; data) vals ~= v.vector;
73         this(cast(void[])vals);
74     }
75     
76     this(mat2 data) {this(cast(void[])data.matrix);}
77     this(mat3 data) {this(cast(void[])data.matrix);}
78     this(mat34 data) {this(cast(void[])data.matrix);}
79     this(mat4 data) {this(cast(void[])data.matrix);}
80     
81     this(Image data) {this(*cast(void[]*)ubyteRawColor(data.rgba.allPixels)[0].ptr);}
82     
83     this(float[] data...) {this(cast(void[])data);}
84     this(ubyte[] data...) {this(cast(void[])data);}
85     
86     this(void[] data) {
87         this_.bind1 = () { bind(); };
88         this_.bind2 = &bind;
89 
90         id_ = glGenBuffer();
91         glBindBuffer(_type, id_);
92         glBufferData(_type, data, _usage);
93         glBindBuffer(_type, 0);
94     }
95     
96     ~this() {
97         glDeleteBuffer(id_);
98     }
99     
100     void opOpAssign(string s)(vec2[] data) {
101         float[] vals;
102         foreach(v; data) vals ~= v.vector;
103         opOpAssign!s(cast(void[])vals);
104     }
105     
106     void opOpAssign(string s)(vec3[] data) {
107         float[] vals;
108         foreach(v; data) vals ~= v.vector;
109         opOpAssign!s(cast(void[])vals);
110     }
111     
112     void opOpAssign(string s)(vec4[] data) {
113         float[] vals;
114         foreach(v; data) vals ~= v.vector;
115         opOpAssign!s(cast(void[])vals);
116     }
117     
118     void opOpAssign(string s)(mat2 data) {opOpAssign!s(cast(void[])data.matrix);}
119     void opOpAssign(string s)(mat3 data) {opOpAssign!s(cast(void[])data.matrix);}
120     void opOpAssign(string s)(mat34 data) {opOpAssign!s(cast(void[])data.matrix);}
121     void opOpAssign(string s)(mat4 data) {opOpAssign!s(cast(void[])data.matrix);}
122     
123     void opOpAssign(string s)(float[] data) {opOpAssign!s(cast(void[])data);}
124     
125     void opOpAssign(string s)(void[] data) {
126         static if (s != "=") return;
127         glBindBuffer(_type, id_);
128         glBufferData(_type, data, _usage);
129         glBindBuffer(_type, 0);
130     }
131     
132     void[] opSlice(size_t offset, size_t length) {
133         void[] data;
134         data.length = length;
135         glGetBufferSubData(_type, cast(uint)offset, data);
136         return data;
137     }
138     
139     uint opCast(T:uint)() {
140         return id_;
141     }
142 
143     void bind(BindBufferTargets type = _type) {
144         glBindBuffer(type, id_);
145     }
146 }